--verified n tested---------final--------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:57:57 01/16/2011 
-- Design Name: 
-- Module Name:    RAM - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE work.LCSE.all;


---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity RAM is
	Port(
			Reset : in std_logic;
			Clk : in std_logic;								
			Databus : inout std_logic_vector(7 downto 0); 		---data bus
			Address : in std_logic_vector(7 downto 0);  			--address bus
			CS : in std_logic;											--chip select
			write_en : in std_logic;   								--write enable
			OE : in std_logic;											--read enable
			Switches : out std_logic_vector(7 downto 0); 		---switch state
			Temp_L : out std_logic_vector(6 downto 0);			---7 segment display lowest temperature value of thermostat
			Temp_H : out std_logic_vector(6 downto 0)				---7 segment display highest temperature value of thermostat
		 );

end RAM;

architecture Behav of RAM is
 
SUBTYPE array8_ram IS std_logic_vector (7 downto 0);
----gpio----------
TYPE gpio_r IS array (64 to 191) of array8_ram;
signal address_gpio :gpio_r;								 ---general purpose RAM (0xFF-0x3F)= 192 bytes
---registers--														reserved 0x2A to 0x30; 0x18 to 0x1f; 0x06 to 0x0f--------
TYPE register_ram_s IS array (0 to 63)of array8_ram;
signal reg_ram_s  :register_ram_s;
signal Databus_i : std_logic_vector(7 downto 0);
signal Databus_en: std_logic;
---------------------------------------------------------------------------------------
signal add_gpio:integer;
signal temp_led: std_logic_vector(7 downto 0);

begin

add_gpio <= Conv_integer(Address)after 1 ns;
Databus <= Databus_i when (Databus_en ='1') else ("ZZZZZZZZ") after 1 ns;

ram: process(Clk,Reset)
	
	begin
		--Databus_en <= '0';
		
		if (Reset='0') then										---all the buffers are reset
			
			reg_ram_s(conv_integer(DMA_RX_BUFFER_MSB)) <=(others => '0') after 1 ns;---RX buffer for DMA --0x00 to 0x02
			reg_ram_s(conv_integer(DMA_RX_BUFFER_MID)) <=(others => '0') after 1 ns;--0x01
			reg_ram_s(conv_integer(DMA_RX_BUFFER_LSB)) <=(others => '0') after 1 ns;--0x02 

			reg_ram_s(conv_integer(NEW_INST))        	 <=(others => '0') after 1 ns;--0x03--flag indicates the arrival of new serial line

			reg_ram_s(conv_integer(DMA_TX_BUFFER_MSB)) <=(others => '0') after 1 ns;--0x04--TX buffer for DMA-- 0x04 to 0x05 
			reg_ram_s(conv_integer(DMA_TX_BUFFER_LSB)) <=(others => '0') after 1 ns;--0x05
				

			reg_ram_s(conv_integer(SWITCH_BASE))		 <=(others => '0') after 1 ns;---0x10 to 0x17
			reg_ram_s(conv_integer(SWITCH_BASE_1))		 <=(others => '0') after 1 ns;
			reg_ram_s(conv_integer(SWITCH_BASE_2))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(SWITCH_BASE_3))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(SWITCH_BASE_4))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(SWITCH_BASE_5))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(SWITCH_BASE_6))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(SWITCH_BASE_7))		 <=(others => '0')after 1 ns;
			
			reg_ram_s(conv_integer(LEVER_BASE))			 <=(others => '0')after 1 ns;--0x20 to 0x29
			reg_ram_s(conv_integer(LEVER_BASE_1))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(LEVER_BASE_2))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(LEVER_BASE_3))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(LEVER_BASE_4))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(LEVER_BASE_5))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(LEVER_BASE_6))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(LEVER_BASE_7))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(LEVER_BASE_8))		 <=(others => '0')after 1 ns;
			reg_ram_s(conv_integer(LEVER_BASE_9))		 <=(others => '0')after 1 ns;
			
			reg_ram_s(conv_integer(T_STAT))				 <=(others => '0')after 1 ns; ---0x31 
			Databus_en <= '0';
			
		elsif (rising_edge(clk)) then
			if (Address< X"40")then 					---write to the special registers
				if ((write_en = '1') and (OE ='0')) then--write
															---load value from data bus to the registers 
					case Address is
					 when  DMA_RX_BUFFER_MSB =>reg_ram_s(0) <= Databus after 1 ns;
					 when  DMA_RX_BUFFER_MID =>reg_ram_s(1) <= Databus after 1 ns;
					 when  DMA_RX_BUFFER_LSB =>reg_ram_s(2) <= Databus after 1 ns;
					 when  NEW_INST 			 =>reg_ram_s(3) <= Databus after 1 ns;
					 when  DMA_TX_BUFFER_MSB =>reg_ram_s(4) <= Databus after 1 ns;
					 when  DMA_TX_BUFFER_LSB =>reg_ram_s(5) <= Databus after 1 ns;
					 
					 when  SWITCH_BASE		 =>reg_ram_s(16) <= Databus after 1 ns;
					 when  SWITCH_BASE_1		 =>reg_ram_s(17) <= Databus after 1 ns;
					 when  SWITCH_BASE_2		 =>reg_ram_s(18) <= Databus after 1 ns;
					 when  SWITCH_BASE_3		 =>reg_ram_s(19) <= Databus after 1 ns;
					 when  SWITCH_BASE_4		 =>reg_ram_s(20) <= Databus after 1 ns;
					 when  SWITCH_BASE_5		 =>reg_ram_s(21) <= Databus after 1 ns;
					 when  SWITCH_BASE_6     =>reg_ram_s(22) <= Databus after 1 ns;
					 when  SWITCH_BASE_7		 =>reg_ram_s(23) <= Databus after 1 ns;
					 
					 when  LEVER_BASE			 =>reg_ram_s(32) <= Databus after 1 ns;
					 when  LEVER_BASE_1		 =>reg_ram_s(33) <= Databus after 1 ns;
					 when  LEVER_BASE_2		 =>reg_ram_s(34) <= Databus after 1 ns;
					 when  LEVER_BASE_3		 =>reg_ram_s(35) <= Databus after 1 ns;
					 when  LEVER_BASE_4		 =>reg_ram_s(36) <= Databus after 1 ns;
					 when  LEVER_BASE_5		 =>reg_ram_s(37) <= Databus after 1 ns;
					 when  LEVER_BASE_6		 =>reg_ram_s(38) <= Databus after 1 ns;
					 when  LEVER_BASE_7		 =>reg_ram_s(39) <= Databus after 1 ns;
					 when  LEVER_BASE_8		 =>reg_ram_s(40) <= Databus after 1 ns;
					 when  LEVER_BASE_9		 =>reg_ram_s(41) <= Databus after 1 ns;
					 
					 when  T_STAT				 =>reg_ram_s(49) <= Databus after 1 ns;
					 when others             =>reg_ram_s	  <=(others => "00000000");
					end case;
																						--read value from the data bus to the registers 
				elsif ( (OE = '1') and (Write_en ='0') )then					--read
					Databus_en<='1'after 1 ns;
					
					case Address is
					 when  DMA_RX_BUFFER_MSB => Databus_i<= reg_ram_s(0) after 1 ns;
					 when  DMA_RX_BUFFER_MID => Databus_i<= reg_ram_s(1) after 1 ns;
					 when  DMA_RX_BUFFER_LSB => Databus_i<= reg_ram_s(2) after 1 ns;
					 when  NEW_INST 			 => Databus_i<= reg_ram_s(3) after 1 ns;
					 when  DMA_TX_BUFFER_MSB => Databus_i<= reg_ram_s(4) after 1 ns;
					 when  DMA_TX_BUFFER_LSB => Databus_i<= reg_ram_s(5) after 1 ns;
					 
					 when  SWITCH_BASE		 => Databus_i<= reg_ram_s(16) after 1 ns;
					 when  SWITCH_BASE_1		 => Databus_i<= reg_ram_s(17) after 1 ns;
					 when  SWITCH_BASE_2		 => Databus_i<= reg_ram_s(18) after 1 ns;
					 when  SWITCH_BASE_3		 => Databus_i<= reg_ram_s(19) after 1 ns;
					 when  SWITCH_BASE_4		 => Databus_i<= reg_ram_s(20) after 1 ns;
					 when  SWITCH_BASE_5		 => Databus_i<= reg_ram_s(21) after 1 ns;
					 when  SWITCH_BASE_6     => Databus_i<= reg_ram_s(22) after 1 ns;
					 when  SWITCH_BASE_7		 => Databus_i<= reg_ram_s(23) after 1 ns;
					 
					 when  LEVER_BASE			 => Databus_i<= reg_ram_s(32) after 1 ns;
					 when  LEVER_BASE_1		 => Databus_i<= reg_ram_s(33) after 1 ns;
					 when  LEVER_BASE_2		 => Databus_i<= reg_ram_s(34) after 1 ns;
					 when  LEVER_BASE_3		 => Databus_i<= reg_ram_s(35) after 1 ns;
					 when  LEVER_BASE_4		 => Databus_i<= reg_ram_s(36) after 1 ns;
					 when  LEVER_BASE_5		 => Databus_i<= reg_ram_s(37) after 1 ns;
					 when  LEVER_BASE_6		 => Databus_i<= reg_ram_s(38) after 1 ns;
					 when  LEVER_BASE_7		 => Databus_i<= reg_ram_s(39) after 1 ns;
					 when  LEVER_BASE_8		 => Databus_i<= reg_ram_s(40) after 1 ns;
					 when  LEVER_BASE_9		 => Databus_i<= reg_ram_s(41) after 1 ns;
					 
					 when  T_STAT				 =>Databus_i	<= reg_ram_s(49)after 1 ns;
					 when others 				 =>Databus_i	<=(others =>'0')after 1 ns;
					end case;
				end if;
			
			elsif (Address > X"40") then -------address of gpio register location is from 40H
				if((Write_en = '1') and (OE ='0'))then--write to the gpio 
					address_gpio(add_gpio) <= Databus after 1 ns;--data on the databus is written in the general purpose RAM
				elsif((Write_en = '0') and (OE ='1')) then -- read operation from gpio
					Databus_en<='1'after 1 ns;
					Databus_i<=address_gpio(add_gpio)after 1 ns;
				end if;
			end if;--address
	end if;--clking
	end process ram;
	


-----switches display-------------------------------

switches(0) <= reg_ram_s(16)(0); 
switches(1) <= reg_ram_s(17)(0); 
switches(2) <= reg_ram_s(18)(0); 
switches(3) <= reg_ram_s(19)(0); 
switches(4) <= reg_ram_s(20)(0); 
switches(5) <= reg_ram_s(21)(0); 
switches(6) <= reg_ram_s(22)(0); 
switches(7) <= reg_ram_s(23)(0); 

-----glow the LED for 7 segment display--------------------------
with temp_led(7 downto 4) select
Temp_H <=
    "0000110" when "0001",  -- 1
    "1011011" when "0010",  -- 2
    "1001111" when "0011",  -- 3
    "1100110" when "0100",  -- 4
    "1101101" when "0101",  -- 5
    "1111101" when "0110",  -- 6
    "0000111" when "0111",  -- 7
    "1111111" when "1000",  -- 8
    "1101111" when "1001",  -- 9
    "1110111" when "1010",  -- A
    "1111100" when "1011",  -- B
    "0111001" when "1100",  -- C
    "1011110" when "1101",  -- D
    "1111001" when "1110",  -- E
    "1110001" when "1111",  -- F
    "0111111" when others;  -- 0

with temp_led(3 downto 0) select 
Temp_L <=
    "0000110" when "0001",  -- 1
    "1011011" when "0010",  -- 2
    "1001111" when "0011",  -- 3
    "1100110" when "0100",  -- 4
    "1101101" when "0101",  -- 5
    "1111101" when "0110",  -- 6
    "0000111" when "0111",  -- 7
    "1111111" when "1000",  -- 8
    "1101111" when "1001",  -- 9
    "1110111" when "1010",  -- A
    "1111100" when "1011",  -- B
    "0111001" when "1100",  -- C
    "1011110" when "1101",  -- D
    "1111001" when "1110",  -- E
    "1110001" when "1111",  -- F
    "0111111" when others;  -- 0

end Behav;
